package com.kitty.game.guard.service;

import com.kitty.game.guard.model.Guard;
import com.kitty.game.guard.model.GuardBox;
import com.kitty.game.role.model.Role;
import com.kitty.game.skill.model.RoleSkill;
import com.kitty.game.config.GuardSet;
import com.kitty.game.config.Skill;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.guard.GuardDataPool;
import com.kitty.game.guard.message.RespGuardsRefresh;
import com.kitty.game.guard.model.CombatGuard;
import com.kitty.game.guard.model.GuardInfo;
import com.kitty.game.role.message.ReqGeneralNotify;
import com.kitty.game.skill.message.RespUpdateSkill;
import com.kitty.game.skill.message.vo.SkillInfo;
import com.kitty.game.skill.service.SkillService;
import com.kitty.game.team.model.Member;
import com.kitty.game.team.message.RespLeaderCombatGuard;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.team.model.Team;
import com.kitty.game.utils.FieldUtils;
import com.kitty.listener.EventDispatcher;
import com.kitty.listener.EventType;
import com.kitty.listener.annotation.EventHandler;
import com.kitty.listener.event.CallGuardEvent;
import com.kitty.listener.event.LoginEvent;
import com.kitty.common.model.Reason;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.MessagePusher;
import com.kitty.game.fight.service.BroadcastService;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.ServerService;
import com.kitty.game.team.service.TeamService;
import org.apache.mina.core.session.IoSession;
import org.nutz.dao.Dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import static com.kitty.game.utils.Const.GOLD_NAME;
import static com.kitty.game.utils.Const.ROLE_RESOURCE_NOT_ENOUGH;

/**
 * 守护
 */
@Service
public class GuardService {
    @Autowired
    Dao dao;
    @Autowired
    RoleService roleService;
    @Autowired
    TeamService teamService;
    @Autowired
    BroadcastService broadcastService;

    /**
     * 登录事件
     */
    @EventHandler(EventType.LOGIN)
    public void handleLoginEvent(LoginEvent loginEvent) {
        Role role = loginEvent.getRole();
        /**加载守护*/
        loadGuard(role);

    }

    /**
     * 守护ID取守护信息
     */
    public Guard getGuard(int guardId, Role role) {
        if (role == null) {
            return null;
        }
        GuardBox guardBox = role.getGuardBox();
        for (Guard guard : guardBox.getGuards()) {
            if (guard.getId() == guardId) {
                return guard;
            }
        }
        return null;
    }

    /**
     * 取守护配置
     */
    public GuardSet getGuardSet(String guardName) {
        return GuardDataPool.guardSetMap.get(guardName);
    }

    /**
     * 增加守护
     *
     * @param guard
     * @return
     */
    private void addGuard(Guard guard, Role role) {
        role.getGuardBox().getGuards().add(guard);
        role.save();
    }

    /**
     * 取出守护列表
     *
     * @param role
     * @return
     */
    public List<Guard> getGuardList(Role role) {
        return role.getGuardBox().getGuards();
    }


    /**
     * 组队成功返回队长的守护
     *
     * @param size
     * @return
     */
    public RespLeaderCombatGuard getFightGuard(Role role, int size) {
        RespLeaderCombatGuard respLeaderCombatGuard = new RespLeaderCombatGuard();
        respLeaderCombatGuard.setList(new ArrayList<>());
        if (size <= 0 || role == null) {
            return respLeaderCombatGuard;
        }
        List<Guard> list = role.getGuardBox().getGuards();
        short i = 1;
        for (Guard guard : list) {
            if (guard.getIsFight() == 0) {
                continue;
            }
            CombatGuard combatGuard = new CombatGuard();
            combatGuard.setIcon(guard.getIcon());
            combatGuard.setName(guard.getName());
            combatGuard.setLevel(guard.getLevel());
            combatGuard.setOrder(i);//位置
            combatGuard.setId(guard.getId());
            respLeaderCombatGuard.getList().add(combatGuard);
        }

        if (respLeaderCombatGuard.getList().size() <= size) {
            return respLeaderCombatGuard;
        }
        int num = respLeaderCombatGuard.getList().size() - size;

        if (num == 1) {
            respLeaderCombatGuard.getList().remove(0);
        } else if (num == 2) {
            respLeaderCombatGuard.getList().remove(0);
            respLeaderCombatGuard.getList().remove(0);
        } else if (num == 3) {
            respLeaderCombatGuard.getList().remove(0);
            respLeaderCombatGuard.getList().remove(0);
            respLeaderCombatGuard.getList().remove(0);
        } else if (num == 4) {
            respLeaderCombatGuard.getList().remove(0);
            respLeaderCombatGuard.getList().remove(0);
            respLeaderCombatGuard.getList().remove(0);
            respLeaderCombatGuard.getList().remove(0);
        }
        return respLeaderCombatGuard;
    }

    /**
     * 取战斗守护列表
     *
     * @param role
     * @param size
     * @return
     */
    public ArrayList<Member> getGuardMembers(Role role, int size) {
        List<Guard> list = role.getGuardBox().getGuards();
        if (list == null || list.size() <= 0) {
            return new ArrayList<>();
        }
        ArrayList<Member> arrayList = new ArrayList<>();

        for (Guard guard : list) {
            if (guard.getIsFight() == 0) {
                continue;
            }
            Member member = new Member();
            member.setRoleId(guard.getId());
            getGuardMember(guard, member, guard.getLevel(), guard.getName());
            member.setGid(guard.getId() + "");
            arrayList.add(member);
        }

        if (arrayList.size() <= size) {
            return arrayList;
        }
        int num = arrayList.size() - size;

        if (num == 1) {
            arrayList.remove(0);
        } else if (num == 2) {
            arrayList.remove(0);
            arrayList.remove(0);
        } else if (num == 3) {
            arrayList.remove(0);
            arrayList.remove(0);
            arrayList.remove(0);
        } else if (num == 4) {
            arrayList.remove(0);
            arrayList.remove(0);
            arrayList.remove(0);
            arrayList.remove(0);
        }
        return arrayList;
    }

    /**
     * 取守护队伍信息
     */
    private void getGuardMember(Guard guard, Member member, short level, String name) {
        member.setIcon(guard.getIcon());
        member.setLevel(level);
        member.setName(name);
        member.setParty("");
        member.setZhanji(0);
        member.setMenpai(guard.getFamily());
        member.setSex((byte) 1);
    }

    /**
     * 添加守护参战
     *
     * @param session
     * @param reqGeneralNotify
     */
    public void addGuard2Team(IoSession session, ReqGeneralNotify reqGeneralNotify) {
        int guardId = Integer.parseInt(reqGeneralNotify.getStatus());
        Role role = SessionUtils.getRoleBySession(session);
        if (role == null) {
            return;
        }
        TeamService teamService = SpringUtils.getBean(TeamService.class);
       // String ipPort = SpringUtils.getBean(ServerService.class).getIpPort();

        Team team = teamService.getTeam(role.getRoleId());
        if (team == null) {
            return;
        }
        List<Guard> list = role.getGuardBox().getGuards();
        Guard guard = null;
        for (Guard result : list) {
            if (result.getId() == guardId) {
                guard = result;
                break;
            }
        }
        if (guard == null) {
            return;
        }
        if (guard.getIsFight() == 0) {
            return;
        }
        Member member = new Member();
        member.setRoleId(guardId);
        getGuardMember(guard, member, role.getLevel(), guard.getName());
        member.setGid(guardId + "");
        member.setGuard(true);
        team.getShouhus().add(member);
        teamService.saveTeam(team);
    }


    /**
     * 购买守护
     *
     * @param session
     * @param reqGeneralNotify
     */
    public void buyGuard(IoSession session, ReqGeneralNotify reqGeneralNotify) {
        Role role = SessionUtils.getRoleBySession(session);
        if (role == null) {
            return;
        }
        String guardName = reqGeneralNotify.getStatus();
        GuardSet guardSet = getGuardSet(guardName);
        for (Guard guard1 : getGuardList(role)) {
            if (guard1.getName().equals(guardName)) {
                return;
            }
        }
        byte castType = guardSet.getCastType();
        int castValue = guardSet.getCastValue();
        if (castType == 1) {//金钱召唤
            if (role.getVoucher() < castValue) {
                if (role.getMoney() < castValue) {
                    MessagePusher.pushMessage(session, new RespMsg("你的金钱不足！请到积分商城购买"));
                    return;
                } else {
                    roleService.subtractMoney(role,  castValue);
                }
            } else {
                role.setVoucher(role.getVoucher() - castValue);
            }

            roleService.updateRoleMoney(role);
        } else if (castType == 2) {//元宝召唤
            if (role.getGold() < castValue) {
                MessagePusher.pushMessage(role, new RespMsg(MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, GOLD_NAME)));
                return;
            }
            SpringUtils.getRoleService().subtractGold(role, castValue, Reason.CALL_GUARD);
            roleService.updateRoleGoldAndSiver(role);
        }

        addGuard(role, guardSet);
    }

    /**根据守护名字添加守护*/
    public void addGuard(Role role, String guardName) {
        GuardSet guardSet = getGuardSet(guardName);
        addGuard(role, guardSet);
    }

    private void addGuard(Role role, GuardSet guardSet) {
        if (role == null || guardSet == null) {return ;}

        Guard guard = new Guard();
        guard.setLevel(role.getLevel());
        guard.setFamily(guardSet.getMenpai());
        setGuardFields(guard,guardSet);
        guard.setId(roleService.getRoleId());
        guard.setHostId(role.getRoleId());
        guard.setName(guardSet.getName());
        guard.setIcon(guardSet.getIcon());
        guard.setColor(guardSet.getColor());
        addGuard(guard, role);
        // 发送数据
        ArrayList<GuardInfo> arrayList = new ArrayList<>();
        GuardInfo guardInfo = new GuardInfo();
        guardInfo.setShouhuId(guard.getId());
        guardInfo.setList(FieldUtils.guardPanelInfo(guardSet, role.getLevel(), guard));
        arrayList.add(guardInfo);
        refreshGuard(role, arrayList);

        /**产生一个召唤守护事件*/
        EventDispatcher.getInstance().fireEvent(new CallGuardEvent(EventType.CALL_GUARD, role, guard.getName()));
        MessagePusher.pushMessage(role, new RespMsg("恭喜恭喜，现在有一位守护来眷顾你了。"));

        //刷新守护列表
        loadGuard(role);
    }

   /**设置守护属性*/
    private void setGuardFields(Guard guard, GuardSet guardSet) {
        int polar =guard.getFamily();
        int level =guard.getLevel();
        short con = 0;
        short str = 0;
        short dex = 0;
        short wiz = 0;
        short metal = 0;
        short wood = 0;
        short water = 0;
        short fire = 0;
        short earth = 0;
        if (polar == 1) {
            con = (short) (guardSet.getTizhi() + level);
            str = (short) (guardSet.getLiliang() + level);
            dex = (short) (guardSet.getMinjie() + level * 2);
            wiz = (short) (guardSet.getLingli() + level * 4);

            metal = (short) (39);
            wood = (short) (6);
            water = (short) (6);
            fire = (short) (14);
            earth = (short) (6);
        } else if (polar == 2) {
            con = (short) (guardSet.getTizhi() + level * 2);
            str = (short) (guardSet.getLiliang() + level);
            dex = (short) (guardSet.getMinjie() + level * 3);
            wiz = (short) (guardSet.getLingli() + level * 2);

            metal = (short) (16);
            wood = (short) (29);
            water = (short) (6);
            fire = (short) (14);
            earth = (short) (6);

        } else if (polar == 3) {
            con = (short) (guardSet.getTizhi() + level);
            str = (short) (guardSet.getLiliang() + level);
            dex = (short) (guardSet.getMinjie() + level * 2);
            wiz = (short) (guardSet.getLingli() + level * 4);

            metal = (short) (16);
            wood = (short) (6);
            water = (short) (29);
            fire = (short) (14);
            earth = (short) (6);

        } else if (polar == 4) {
            con = (short) (guardSet.getTizhi() + level);
            str = (short) (guardSet.getLiliang() + level * 4);
            dex = (short) (guardSet.getMinjie() + level * 2);
            wiz = (short) (guardSet.getLingli() + level);

            metal = (short) (16);
            wood = (short) (6);
            water = (short) (6);
            fire = (short) (14);
            earth = (short) (39);

        } else if (polar == 5) {
            con = (short) (guardSet.getTizhi() + level);
            str = (short) (guardSet.getLiliang() + level * 4);
            dex = (short) (guardSet.getMinjie() + level * 2);
            wiz = (short) (guardSet.getLingli() + level);

            metal = (short) (6);
            wood = (short) (16);
            water = (short) (6);
            fire = (short) (14);
            earth = (short) (39);
        }
        if (guardSet.getColor() == 3) {
            metal = (short) (metal * 1.5);
            wood = (short) (wood * 1.5);
            water = (short) (water * 1.5);
            fire = (short) (fire * 1.5);
            earth = (short) (earth * 1.5);
        } else if (guardSet.getColor() == 2) {
            metal = (short) (metal * 1.2);
            wood = (short) (wood * 1.2);
            water = (short) (water * 1.2);
            fire = (short) (fire * 1.2);
            earth = (short) (earth * 1.2);
        }
        guard.setStr(str);
        guard.setDex(dex);
        guard.setWiz(wiz);
        guard.setCon(con);
        guard.setMetal(metal);
        guard.setWood(wood);
        guard.setWater(water);
        guard.setFire(fire);
        guard.setEarth(earth);
    }

    /**
     * 更改守护参战的状态
     */
    public void fightStatus(Role role, int cheerId, byte cheer, int restId) {
        setGuardState(role, cheerId, cheer);
        if (restId > 0) {
            setGuardState(role, restId, (byte) 0);
        }
        Team team = teamService.getTeam(role.getRoleId());
        if (team == null) {
            sendFightGuardInfo(role);
            return;
        }
        SpringUtils.getTeamService().sendGuardToTeam(role, team);
    }


    private void setGuardState(Role role, int guardId, byte state) {
        for (Guard guard : role.getGuardBox().getGuards()) {
            if (guard.getId() == guardId) {
                guard.setIsFight(state);
                role.save();

                ArrayList<GuardInfo> arrayList = new ArrayList<>();
                GuardInfo guardInfo = new GuardInfo();
                guardInfo.setShouhuId(guard.getId());
                guardInfo.setList(new ArrayList<>());
                guardInfo.getList().add(new FiedValue(280, 3, guard.getIsFight()));
                guardInfo.getList().add(new FiedValue(853, 1, guard.getPos()));
                arrayList.add(guardInfo);
                refreshGuard(role, arrayList);
                break;
            }
        }
    }


    /**
     * 参战守护封包
     */
    private void sendFightGuardInfo(Role role) {
        RespLeaderCombatGuard respLeaderCombatGuard = new RespLeaderCombatGuard();
        respLeaderCombatGuard.setList(new ArrayList<>());
        for (Guard guard : role.getGuardBox().getGuards()) {
            if (guard.getIsFight() == 1) {
                CombatGuard combatGuard = new CombatGuard();
                combatGuard.setName(guard.getName());
                combatGuard.setId(guard.getId());
                combatGuard.setLevel(role.getLevel());
                combatGuard.setIcon(guard.getIcon());
                respLeaderCombatGuard.getList().add(combatGuard);
            }
        }
        MessagePusher.pushMessage(role, respLeaderCombatGuard);
    }

    /**
     * 加载守护
     */

    public void loadGuard(Role role) {
        List<Guard> list = getGuardList(role);
        ArrayList<GuardInfo> arrayList = new ArrayList<>();
        byte i = 0;
        for (Guard guard : list) {
            i++;
            guard.setPos(i);
            GuardInfo guardInfo = new GuardInfo();
            GuardSet guardSet = getGuardSet(guard.getName());
            guardInfo.setShouhuId(guard.getId());
            guardInfo.setList(FieldUtils.guardPanelInfo(guardSet, role.getLevel(), guard));
            arrayList.add(guardInfo);
        }
        setGuardAttrib(role);
        refreshGuard(role, arrayList);

        /**加载守护技能*/
        for (Guard guard : list) {
            List<Integer> tempList =new ArrayList<>(guard.getAttackSkills());
            tempList.addAll(guard.getAssistSkills());
            RespUpdateSkill respUpdateSkill = new RespUpdateSkill();
            respUpdateSkill.setId(guard.getId());
            ArrayList<SkillInfo> skillInfos = new ArrayList<>();
            for (Integer skillId : tempList) {
                Skill skill = SpringUtils.getSkillService().getSkillInfo(skillId);
                RoleSkill roleSkill = new RoleSkill(skill, guard.getLevel());
                skillInfos.add(SpringUtils.getBean(SkillService.class).getSkillInfo(roleSkill, 0));
            }
            respUpdateSkill.setList(skillInfos);
            MessagePusher.pushMessage(role, respUpdateSkill);
        }


    }

    /**
     * 更新守护技能状态
     */
    public void chargeSkillType(Role role, ReqGeneralNotify reqGeneralNotify) {
        int guardId = Integer.parseInt(reqGeneralNotify.getStatus());
        for (Guard guard : role.getGuardBox().getGuards()) {
            if (guard.getId() == guardId) {
                guard.setType(Byte.parseByte(reqGeneralNotify.getString()));
                role.save();

                ArrayList<GuardInfo> arrayList = new ArrayList<>();
                GuardInfo guardInfo = new GuardInfo();
                GuardSet guardSet = getGuardSet(guard.getName());
                guardInfo.setShouhuId(guard.getId());
                guardInfo.setList(FieldUtils.guardPanelInfo(guardSet, role.getLevel(), guard));
                arrayList.add(guardInfo);
                refreshGuard(role, arrayList);
                break;
            }
        }
    }


    /**
     * 刷新守护列表
     */

    public void refreshGuard(Role role, ArrayList<GuardInfo> arrayList) {
        RespGuardsRefresh respGuardsRefresh = new RespGuardsRefresh();
        respGuardsRefresh.setList(arrayList);
        MessagePusher.pushMessage(role, respGuardsRefresh);
    }

    /**
     * 守护等级需要与角色等级相同 升级之后给守护设置技能
     */
    public void setGuardAttrib(Role role) {
        ArrayList<Guard> guards = role.getGuardBox().getGuards();
        guards.forEach(guard -> {
            GuardSet guardSet =getGuardSet(guard.getName());
            guard.setLevel(role.getLevel());
            setGuardFields(guard,guardSet);
            setGuardSkill(guard);
        });
        role.save();
    }


    /**
     * 宠物升级置宠物技能
     */
    private void setGuardSkill(Guard guard) {
        byte polar = (byte) guard.getFamily();
        if (guard.getLevel() >= 10) {// 一阶技能
            if (polar == 1) {
                guard.getAttackSkills().add(11);
                guard.getAssistSkills().add(31);
            } else if (polar == 2) {
                guard.getAttackSkills().add(61);
                guard.getAssistSkills().add(81);
            } else if (polar == 3) {
                guard.getAttackSkills().add(110);
                guard.getAssistSkills().add(131);
            } else if (polar == 4) {
                guard.getAttackSkills().add(501);
                guard.getAssistSkills().add(181);
            } else if (polar == 5) {
                guard.getAttackSkills().add(501);
                guard.getAssistSkills().add(231);
            }
        }
        if (guard.getLevel() >= 40) {//二阶技能 三阶技能
            if (polar == 1) {
                guard.getAttackSkills().add(12);
                guard.getAttackSkills().add(13);
                guard.getAssistSkills().add(32);
                guard.getAssistSkills().add(33);
            } else if (polar == 2) {
                guard.getAttackSkills().add(62);
                guard.getAttackSkills().add(63);
                guard.getAssistSkills().add(82);
                guard.getAssistSkills().add(83);
            } else if (polar == 3) {
                guard.getAttackSkills().add(111);
                guard.getAttackSkills().add(112);
                guard.getAssistSkills().add(132);
                guard.getAssistSkills().add(133);
            } else if (polar == 4) {
                guard.getAssistSkills().add(182);
                guard.getAssistSkills().add(183);
            } else if (polar == 5) {
                guard.getAssistSkills().add(232);
                guard.getAssistSkills().add(233);
            }
        }
        if (guard.getLevel() >= 60) {//四阶技能
            if (polar == 1) {
                guard.getAttackSkills().add(14);
                guard.getAssistSkills().add(34);
            } else if (polar == 2) {
                guard.getAttackSkills().add(64);
                guard.getAssistSkills().add(84);
            } else if (polar == 3) {
                guard.getAttackSkills().add(113);
                guard.getAssistSkills().add(134);
            } else if (polar == 4) {
                guard.getAssistSkills().add(184);
            } else if (polar == 5) {
                guard.getAssistSkills().add(234);
            }
        }
        if (guard.getLevel() >= 100) {//四阶技能
            if (polar == 1) {
                guard.getAttackSkills().add(15);
                guard.getAssistSkills().add(35);
            } else if (polar == 2) {
                guard.getAttackSkills().add(65);
                guard.getAssistSkills().add(85);
            } else if (polar == 3) {
                guard.getAttackSkills().add(114);
                guard.getAssistSkills().add(135);
            } else if (polar == 4) {
                guard.getAssistSkills().add(185);
            } else if (polar == 5) {
                guard.getAssistSkills().add(235);
            }
        }
    }
}
